package com.yanqu.road.server.manger.cross3;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.config.goods.WasheReplaceBoxData;
import com.yanqu.road.entity.enums.eShopType;
import com.yanqu.road.logic.bussiness.servercenter.ChannelActivityBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.helper.CrossChannelHelper;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 跨区域活动
 * （定时读取活动配置，等ActivityMgr需要的时候再过来拿）
 */
public class ChannelActivityMgr extends TempMgr {

    private static final Object lock = new Object();

    /**
     * 全部活动信息
     */
    private static Map<Integer, ActivityInfo> activityInfoMap = new ConcurrentHashMap<>();

    /**
     * 活动condition
     */
    private static Map<Integer, List<ActivityConditionInfo>> conditionInfoMap = new ConcurrentHashMap<>();

    /**
     * 活动商店
     */
    private static Map<Integer, Map<Integer, MallInfo>> activityMallMap = new ConcurrentHashMap<>();

    /**
     * 活动配置
     */
    private static Map<Integer, Map<String, ActivityConfig>> activityConfigMap = new ConcurrentHashMap<>();

    /**
     * 活动区服ID
     */
    private static Set<Long> serverIdSet = new ConcurrentHashSet<>();

    /**
     * 瓦舍活动商店替换缓存 活动 卡类型 当日随机结果
     */
    private static Map<Integer, Map<Integer, WasheReplaceBoxData>> washeReplaceMapByServerId = new ConcurrentHashMap<>();

    /**
     * 重新刷活动
     */
    public static void reloadActivity() {
        try {

            // 先检查有没有数据库连接配置
            String dbParam = ChannelConfig.CHANNEL_CENTER_DB_PARAM;
            if ("0".equals(dbParam)) {
                getLogger().info("[ ChannelConfig.CHANNEL_CENTER_DB_PARAM ] is zero!");
                return;
            }

            Map<Integer, ActivityInfo> tmpActivityMap;
            Map<Integer, List<ActivityConditionInfo>> tmpConditionMap;
            Map<Integer, Map<Integer, MallInfo>> tmpMallMap;
            Map<Integer, Map<String, ActivityConfig>> tmpConfigMap;
            Set<Long> tmpServerIdSet;

            List<Integer> tmpActivityIdList = new ArrayList<>();
            int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());

            // 【activityInfo】
            // 全部活动
            tmpActivityMap = ChannelActivityBussiness.getAllActivityInfoMap(dbParam, GameServer.getInstance().getServerId(), ChannelConfig.CHANNEL_ACTIVITY_TIME_ZONE);
            // 瓦舍活动
            Map<Integer, ActivityInfo> recentWasheInfoMap = ChannelActivityBussiness.getRecentWasheActivityInfoMap(dbParam, channelId, ChannelConfig.CHANNEL_ACTIVITY_TIME_ZONE);
            for (ActivityInfo washeInfo : recentWasheInfoMap.values()) {
                tmpActivityMap.put(washeInfo.getActivityId(), washeInfo);
            }
            tmpServerIdSet = new ConcurrentHashSet<>();
            long now = System.currentTimeMillis() / 1000;
            for (ActivityInfo activityInfo : tmpActivityMap.values()) {
                if (now >= (activityInfo.getBeginShowTime() - 2 * DateHelper.DAY_SECONDS)
                        && now < (activityInfo.getEndShowTime() + 8 * DateHelper.DAY_SECONDS)) { // 提前2天，过期8天
                    activityInfo.setCrossId(CrossChannelHelper.getCross3Id(GameServer.getInstance().getServerId()));
                    tmpActivityIdList.add(activityInfo.getActivityId());
                    tmpServerIdSet.addAll(activityInfo.getServerIdList());
                } else {
                    tmpActivityMap.remove(activityInfo.getActivityId());
                    if (washeReplaceMapByServerId.containsKey(activityInfo.getActivityId())){
                        washeReplaceMapByServerId.remove(activityInfo.getActivityId());
                    }
                }
            }
            tmpServerIdSet.remove(0L); // 移除非区服ID（瓦舍的区服ID是0）
            // 【condition】
            tmpConditionMap = ChannelActivityBussiness.getActivityConditionInfoMap(dbParam, tmpActivityIdList);
            // 【mallInfo】
            List<MallInfo> tmpReplaceMap = new ArrayList<>();
            //先清空所有缓存的id
            for (Map<Integer, WasheReplaceBoxData> washeReplaceBoxDataMap : washeReplaceMapByServerId.values()){
                for (WasheReplaceBoxData data:washeReplaceBoxDataMap.values()){
                    data.getAllMallIdSet().clear();
                }
            }

            tmpMallMap = ChannelActivityBussiness.getActivityMallInfoMap(dbParam, tmpActivityIdList);
            for (Map<Integer, MallInfo> infoMap : tmpMallMap.values()) {
                for (MallInfo mallInfo : infoMap.values()) {
                    if (mallInfo.getChannelId() != 0 && mallInfo.getChannelId() != channelId) {
                        infoMap.remove(mallInfo.getMallId()); // 过滤非当前地区的商店
                        continue;
                    }
                    if (mallInfo.getShopType() == eShopType.WaSheRefresh.getValue()){
                        MallInfo clone = mallInfo.getClone();
                        //添加到待替换列表
                        tmpReplaceMap.add(clone);
                        //添加到随机池子
                        addToReplaceWaSheBoxItem(clone);
                        //挤掉原本的
                        infoMap.put(clone.getMallId(),clone);
                    }
                }
            }

            //遍历washeReplaceMapByServerId中的元素
            for (Map<Integer, WasheReplaceBoxData> washeReplaceBoxDataMap : washeReplaceMapByServerId.values()){
                for (WasheReplaceBoxData washeReplaceBoxData : washeReplaceBoxDataMap.values()){
                    //把要替换的数据遍历查看是否需要更新
                    washeReplaceBoxData.checkRandomMallId();
                    getLogger().debug("瓦舍活动商店:{}类型:{}随机卡片为:{}",washeReplaceBoxData.getActivityId(),washeReplaceBoxData.getType(),washeReplaceBoxData.getChooseMallId());
                }
            }

            //把要替换的数据遍历查看
            for (MallInfo cloneMallInfo : tmpReplaceMap){
                checkCanShowSpecialWasheCard(cloneMallInfo);
            }


            // 【config】
            tmpConfigMap = ChannelActivityBussiness.getActivityConfigMap(dbParam, tmpActivityIdList);

            synchronized (lock) {
                activityInfoMap = tmpActivityMap;
                conditionInfoMap = tmpConditionMap;
                activityMallMap = tmpMallMap;
                activityConfigMap = tmpConfigMap;
                serverIdSet = tmpServerIdSet;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 检查218类型的卡牌是否可以展示出来
     * @param mallInfo
     */
    public static void checkCanShowSpecialWasheCard(MallInfo mallInfo){
        if (!washeReplaceMapByServerId.containsKey(mallInfo.getActivityId())){
            getLogger().error("瓦舍活动商店活动:{}id:{}没有替换数据",mallInfo.getActivityId(),mallInfo.getMallId());
            mallInfo.setShow(false);
            return;
        }
        int key = StringUtils.parseInt(mallInfo.getExtendParam());
        if (!washeReplaceMapByServerId.get(mallInfo.getActivityId()).containsKey(key)){
            getLogger().error("瓦舍活动商店活动:{}类型:{}没有替换数据",mallInfo.getActivityId(),mallInfo.getParam());
            mallInfo.setShow(false);
            return;
        }
        WasheReplaceBoxData washeReplaceBoxData = washeReplaceMapByServerId.get(mallInfo.getActivityId()).get(key);
        washeReplaceBoxData.checkRandomMallId();
        if (washeReplaceBoxData.getChooseMallId() == 0){
            getLogger().error("瓦舍活动商店活动:{}类型:{}没有初始化替换数据",mallInfo.getActivityId(),mallInfo.getParam());
            mallInfo.setShow(false);
            return;
        }
        if (washeReplaceBoxData.getChooseMallId() != mallInfo.getMallId()){
            mallInfo.setShow(false);
            return;
        }

        mallInfo.setShow(true);
    }


    /**
     * 获取活动区服ID
     */
    public static Set<Long> getServerIdSet() {
        return serverIdSet;
    }

    /**
     * 把跨区域活动数据加到参数的Map中
     */
    public static void addChannelActivity(Map<Integer, ActivityInfo> tmpActivityMap,
                                          Map<Integer, List<ActivityConditionInfo>> tmpConditionMap,
                                          Map<Integer, Map<Integer, MallInfo>> tmpMallMap,
                                          Map<Integer, Map<String, ActivityConfig>> tmpConfigMap) {
        Map<Integer, ActivityInfo> copyActivityInfoMap;
        Map<Integer, List<ActivityConditionInfo>> copyConditionInfoMap;
        Map<Integer, Map<Integer, MallInfo>> copyActivityMallMap;
        Map<Integer, Map<String, ActivityConfig>> copyActivityConfigMap;

        synchronized (lock) {
            copyActivityInfoMap = new ConcurrentHashMap<>(activityInfoMap);
            copyConditionInfoMap = new ConcurrentHashMap<>(conditionInfoMap);
            copyActivityMallMap = new ConcurrentHashMap<>(activityMallMap);
            copyActivityConfigMap = new ConcurrentHashMap<>(activityConfigMap);
        }

        for (ActivityInfo activityInfo : copyActivityInfoMap.values()) {
            tmpActivityMap.put(activityInfo.getActivityId(), activityInfo);
        }
        for (Map.Entry<Integer, List<ActivityConditionInfo>> entry : copyConditionInfoMap.entrySet()) {
            tmpConditionMap.put(entry.getKey(), entry.getValue());
        }
        for (Map.Entry<Integer, Map<Integer, MallInfo>> entry : copyActivityMallMap.entrySet()) {
            tmpMallMap.put(entry.getKey(), entry.getValue());
        }
        for (Map.Entry<Integer, Map<String, ActivityConfig>> entry : copyActivityConfigMap.entrySet()) {
            tmpConfigMap.put(entry.getKey(), entry.getValue());
        }
    }

    public static int getChannelActivityMaxRank(int activityId, int conditionType) {
        // 拿condition
        List<ActivityConditionInfo> infoList = conditionInfoMap.get(activityId);
        if (infoList == null) {
            infoList = ChannelActivityBussiness.getActivityConditionInfoList(ChannelConfig.CHANNEL_CENTER_DB_PARAM, activityId, conditionType);
        }
        if (infoList == null || infoList.isEmpty()) {
            getLogger().error("activityId = {}, conditionType = {}, can not get max rank!", activityId, conditionType);
            return CrossChannelHelper.getTempRankSize(); // 有问题就返回默认长度
        }
        // 按类型过滤下
        infoList = infoList.stream().filter(item -> item.getType() == conditionType).collect(Collectors.toList());
        return ActivityHelper.getMaxRank(infoList);
    }

    public static int getChannelRankPartNum(int activityId) {
        ActivityInfo info = activityInfoMap.get(activityId);
        if (info != null) {
            try {
                int value = Integer.valueOf(info.getParam6());
                if (value > 0) {
                    return value;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return CrossChannelHelper.getTempChannelRankPartNum();
    }

    public static void addToReplaceWaSheBoxItem(MallInfo mallInfo){
        if (washeReplaceMapByServerId == null){
            washeReplaceMapByServerId = new ConcurrentHashMap<>();
        }
        if (!washeReplaceMapByServerId.containsKey(mallInfo.getActivityId())){
            washeReplaceMapByServerId.put(mallInfo.getActivityId(),new ConcurrentHashMap<>());
        }
        Map<Integer, WasheReplaceBoxData> activityReplaceMap = washeReplaceMapByServerId.get(mallInfo.getActivityId());
        int key = StringUtils.parseInt(mallInfo.getExtendParam());
        if (!activityReplaceMap.containsKey(key)){
            WasheReplaceBoxData boxData = new WasheReplaceBoxData();
            boxData.setActivityId(mallInfo.getActivityId());
            boxData.setType(key);
            boxData.setLastUpdateTime(0);
            boxData.setAllMallIdSet(new HashSet<>());
            activityReplaceMap.put(key,boxData);
        }
        activityReplaceMap.get(key).getAllMallIdSet().add(mallInfo.getMallId());
    }


    @Override
    public boolean init() throws Exception {
        return true;
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }
}
